package ws.jdbc.concurrent.driver.sqlserver.tds;

import java.io.IOException;
import java.nio.ByteBuffer;
import ws.jdbc.concurrent.driver.sqlserver.tds.datastreamtypes.B_VARCHAR;

/**
 * This class represents a property of the {@code COLINFO} token.
 *
 * <p>
 * <a href="http://msdn.microsoft.com/en-us/library/dd358065">Reference</a>
 * </p>
 * 
 * @author Wilson Santos, 36228 <wilson.santos@ua.pt>
 */
public class ColProperty {

  /** The column was the result of an expression. */
  private static final byte EXPRESSION = 0x4;
  /** The column is part of a key for the associated table. */
  private static final byte KEY = 0x8;
  /** 
   * The column was not a member of the selected list, but was added because it
   * was part of a key for associated table.
   */
  private static final byte HIDDEN = 0x10;
  /**
   * The column name is different than the selected list column name in the case
   * of a column alias.
   */
  private static final byte DIFFERENT_NAME = 0x20;
  /** The column number in the result set. */
  private byte colNum;
  /**
   * The number of the base table that the column was derived from.
   * The value is 0 if the value of Status is EXPRESSION.
   */
  private byte tableNum;
  /** Status flags (EXPRESSION, KEY, HIDDEN and DIFFERENT_NAME). */
  private byte status;
  /**
   * The base column name.
   * This only occurs if DIFFERENT_NAME is set in Status.
   */
  private B_VARCHAR colName;

  public int read(final ByteBuffer stream) throws IOException {
    assert stream != null;

    VariableLengthDataStreamReader vldsreader = new VariableLengthDataStreamReader(stream);

    //  ColNum
    colNum = stream.get();
    //  TableNum
    tableNum = stream.get();
    //  Status
    status = stream.get();
    //  [ColName]
    if (isDifferentName()) {
      colName = vldsreader.readBVarChar();
    }

    return 3 + vldsreader.getBytesRead();
  }

  private boolean isExpression() {
    return (status & EXPRESSION) == EXPRESSION;
  }

  private boolean isKey() {
    return (status & KEY) == KEY;
  }

  private boolean isHidden() {
    return (status & HIDDEN) == HIDDEN;
  }

  private boolean isDifferentName() {
    return (status & DIFFERENT_NAME) == DIFFERENT_NAME;
  }

  @Override
  public String toString() {
    return "ColProperty{"
            + "\n  colNum=" + colNum
            + "\n  tableNum=" + tableNum
            + "\n  status=" + status
            + "\n  colName=" + colName
            + "\n}\n";
  }
}
